home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / misc / CapiRexxVoiceM.lha / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  7.2 KB  |  362 lines

  1. /*
  2. **
  3. **    $Id: process.c,v 1.2 1995/10/07 02:52:52 chris Exp $
  4. **    $Revision: 1.2 $
  5. **
  6. **    $Filename: developer/process.c $
  7. **    $Author: chris $
  8. **    $Date: 1995/10/07 02:52:52 $
  9. **    $Portability: AMIGADOS $
  10. **
  11. **    Prozess-Verwaltung
  12. **
  13. **    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RELOG AG.
  14. **
  15. **    COPYRIGHT (C) 1991-1996 BY RELOG AG, ZUERICH. ALL RIGHTS RESERVED.
  16. **    NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED
  17. **    IN ANY FORM OR BY ANY MEANS,  WITHOUT THE PRIOR WRITTEN PERMISSION
  18. **    OF RELOG AG.
  19. **
  20. */
  21.  
  22. #include "OS.h"
  23.  
  24. #define  _PROCESS
  25. #include "process.h"
  26. #include "arexx.h"
  27.  
  28. #include <proto/exec.h>
  29. #include <exec/memory.h>
  30. #include <proto/dos.h>
  31. #include <dos/dostags.h>
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35.  
  36. #define STACKSIZE        8192        /* Stapelgrösse des Message-Handler-Prozesses */
  37.  
  38.  
  39. struct ProcEnv
  40. {
  41.     struct Message        Message;        /* Wird dem Prozess geschickt */
  42.  
  43.     PROCFUNC            Func;            /* Handler-Funktion */
  44.     VOID                *Para;            /* Parameter der Handler-Funktion */
  45.  
  46.     struct Process        *Process;        /* Zeiger auf Prozess oder NULL */
  47.  
  48.     struct ARexxPort    *RexxPort;        /* Zeiger auf REXX-Port */
  49.     char                PortName[32];    /* REXX-Port-Name */
  50. };
  51.  
  52.  
  53. struct MsgPort    *proclistport;            /* Liste aller ProcEnv-Strukturen */
  54.  
  55.  
  56. /****** Process_Create ******************************************************
  57. *
  58. *   NAME
  59. *       Process_Create -- Create a process
  60. *
  61. *   SYNOPSIS
  62. *       pid = Process_Create( func, userdata, name, priority );
  63. *
  64. *       U32 Process_Create( BOOL (*)( U32 ), U32, U8 *, S8 );
  65. *
  66. *   FUNCTION
  67. *       This function creates a process which will basically sleep. Whenever
  68. *       Process_Wakeup() with its pid is called, the process will wake up and
  69. *       call `func' with `userdata' as its sole argument. When the function
  70. *       returns, the process will fall asleep anew.
  71. *       If func returns FALSE, the process will self-terminate.
  72. *
  73. *       Additionally, an AREXX message port will be created, and AREXX
  74. *       messages will be handled.
  75. *
  76. *   INPUTS
  77. *       func     - Function to be called, or NULL if this is an AREXX
  78. *                  handler process.
  79. *       userdata - Will be passed to func and all AREXX functions
  80. *       name     - Name of the process
  81. *       priority - Process priority [-128..127]
  82. *
  83. *   RESULT
  84. *       pid - Process ID.
  85. *
  86. *   SEE ALSO
  87. *
  88. ****************************************************************************/
  89.  
  90. static VOID __saveds ProcessEntry( VOID )
  91. {
  92.     struct Process    *me = (struct Process *)FindTask( NULL );
  93.     struct ProcEnv    *env;
  94.  
  95.     /*
  96.     **    Startup-Message mit Environment abholen
  97.     */
  98.     WaitPort( &me->pr_MsgPort );
  99.     env = (struct ProcEnv *)GetMsg( &me->pr_MsgPort );
  100.  
  101.  
  102.     /*
  103.     **    ARexx-Port erzeugen, falls keine Handler-Funktion angegeben wurde
  104.     */
  105.     if (env->Func == NULL)
  106.     {
  107.         OS_sprintf( env->PortName, "AM-%08lx", env->Process );
  108.         env->RexxPort = ARexx_CreatePort( env->PortName, env->Para );    /* $$$ Abfrage? */
  109.     }
  110.  
  111.  
  112.     /*
  113.     **    Initialisierung ist jetzt beendet, Env wird zurückgeschickt.
  114.     */
  115.     ReplyMsg( &env->Message );
  116.  
  117.  
  118.     /*
  119.     **    Hauptschleife
  120.     */
  121.     for (;;)
  122.     {
  123.         U32 mask = SIGBREAKF_CTRL_C | SIGF_SINGLE;
  124.  
  125.         if (env->RexxPort != NULL)
  126.             mask |= 1UL << env->RexxPort->Port->mp_SigBit;
  127.  
  128.         if (Wait( mask ) & SIGBREAKF_CTRL_C )
  129.                 break;
  130.  
  131.         if (env->Func != NULL)
  132.         {
  133.             if (!(*env->Func)( env->Para ))
  134.                 break;
  135.         }
  136.         else if (env->RexxPort != NULL)
  137.         {
  138.             ARexx_HandleMessages( env->RexxPort );
  139.         }
  140.     }
  141.  
  142.     if (env->RexxPort != NULL)
  143.     {
  144.         ARexx_DeletePort( env->RexxPort );
  145.         env->RexxPort = NULL;
  146.     }
  147.  
  148.     env->Process = NULL;
  149. }
  150.  
  151.  
  152. U32
  153. Process_Create( PROCFUNC func, VOID *para, U8 *name, S8 pri )
  154. {
  155.     struct ProcEnv *env;
  156.  
  157.     if (proclistport == NULL)
  158.     {
  159.         printf( "Creating the first process, initializing proclistport\n" );
  160.         if (!(proclistport = CreateMsgPort()))
  161.             return NULL;
  162.     }
  163.  
  164.     if ((env = OS_Malloc( sizeof( *env ) )) != NULL)
  165.     {
  166.         env->Func    = func;
  167.         env->Para    = para;
  168.  
  169.         /*
  170.         **    Message-Handler-Prozess erzeugen
  171.         */
  172.         if (env->Process = CreateNewProcTags(
  173.                 NP_Entry,        (U32)ProcessEntry,
  174.                 NP_Name,        (U32)name,
  175.                 NP_Priority,    (S32)pri,
  176.                 NP_StackSize,    STACKSIZE,
  177.                 NP_Output,        Output(),
  178.                 NP_CloseOutput,    FALSE,
  179.                 TAG_DONE
  180.         ))
  181.         {
  182.             if (env->Message.mn_ReplyPort = CreateMsgPort())
  183.             {
  184.                 /*
  185.                 **    Startup-Message zum neuen Prozess schicken und warten,
  186.                 **    bis sie wieder zurückgekommen ist
  187.                 */
  188.                 PutMsg( &env->Process->pr_MsgPort, &env->Message );
  189.                 WaitPort( env->Message.mn_ReplyPort );
  190.                 DeleteMsgPort( env->Message.mn_ReplyPort );
  191.                 env->Message.mn_ReplyPort = NULL;
  192.  
  193.                 /* env in die Prozessliste eintragen */
  194.                 PutMsg( proclistport, &env->Message );
  195.  
  196.                 printf( "Created process 0x%08lx\n", env );
  197.                 return (U32)env;
  198.             }
  199.  
  200.             /* $$$ Oehm... da liegt jetzt so ein toter Prozess rum! */
  201.         }
  202.  
  203.         OS_Free( env );
  204.     }
  205.  
  206.     return (U32)NULL;
  207. }
  208.  
  209.  
  210. /****** Process_Delete ******************************************************
  211. *
  212. *   NAME
  213. *       Process_Delete -- Delete a process
  214. *
  215. *   SYNOPSIS
  216. *       Process_Delete( pid );
  217. *
  218. *       VOID Process_Delete( U32 );
  219. *
  220. *   FUNCTION
  221. *       This function kills a process.
  222. *
  223. *   INPUTS
  224. *
  225. *   RESULT
  226. *
  227. *   SEE ALSO
  228. *
  229. ****************************************************************************/
  230.  
  231. VOID
  232. Process_Delete( U32 pid )
  233. {
  234.     struct ProcEnv *env = (struct ProcEnv *)pid;
  235.  
  236.     Forbid();
  237.     if (Process_IsValidPID( pid ))
  238.     {
  239.         U16 i;
  240.  
  241.         Remove( &env->Message.mn_Node );
  242.  
  243.         for (i=0; i < 20; ++i)    /* 4 Sekunden */
  244.         {
  245.             if (env->Process != NULL)
  246.                 Signal( &env->Process->pr_Task, SIGBREAKF_CTRL_C );
  247.  
  248.             if (env->Process == NULL)
  249.                 break;
  250.  
  251.             OS_Delay( 100 );
  252.         }
  253.  
  254.         printf( "Deleting process 0x%08lx\n", env );
  255.         OS_Free( env );
  256. /*        env = NULL; */
  257.     }
  258.  
  259.     if (ISLISTEMPTY( (IC_LIST *)&proclistport->mp_MsgList ))
  260.     {
  261.         printf( "This was the last process, deleting proclistport\n" );
  262.         DeleteMsgPort( proclistport );
  263.         proclistport = NULL;
  264.     }
  265.     Permit();
  266. }
  267.  
  268.  
  269. /****** Process_WakeUp ******************************************************
  270. *
  271. *   NAME
  272. *       Process_WakeUp -- Signal a process to wake up
  273. *
  274. *   SYNOPSIS
  275. *       Process_WakeUp( pid );
  276. *
  277. *       VOID Process_WakeUp( U32 );
  278. *
  279. *   FUNCTION
  280. *
  281. *   INPUTS
  282. *
  283. *   RESULT
  284. *
  285. *   SEE ALSO
  286. *
  287. ****************************************************************************/
  288.  
  289. VOID
  290. Process_WakeUp( U32 pid )
  291. {
  292.     struct ProcEnv *env = (struct ProcEnv *)pid;
  293.  
  294.     Forbid();
  295.     if (Process_IsValidPID( pid ))
  296.     {
  297.         Signal( &env->Process->pr_Task, SIGF_SINGLE );
  298.     }
  299.     Permit();
  300. }
  301.  
  302.  
  303. /****** Process_IsValidPID ******************************************************
  304. *
  305. *   NAME
  306. *       Process_IsValidPID -- Test if a pid is valid
  307. *
  308. *   SYNOPSIS
  309. *       Process_IsValidPID( pid );
  310. *
  311. *       VOID Process_IsValidPID( U32 );
  312. *
  313. *   FUNCTION
  314. *       Tests if there's a process running with pid.
  315. *
  316. *   INPUTS
  317. *
  318. *   RESULT
  319. *       TRUE if valid, FALSE if not.
  320. *
  321. *   SEE ALSO
  322. *
  323. ****************************************************************************/
  324.  
  325. BOOL
  326. Process_IsValidPID( U32 pid )
  327. {
  328.     struct ProcEnv *env = (struct ProcEnv *)pid, *e2;
  329.  
  330.     Forbid();
  331.     if (proclistport != NULL)
  332.     {
  333.         DOLIST( (IC_LIST *)&proclistport->mp_MsgList, e2 )
  334.         {
  335.             if (e2 == env)
  336.             {
  337.                 Permit();
  338.                 return TRUE;
  339.             }
  340.         }
  341.     }
  342.     Permit();
  343.  
  344.     printf( "WARNING: IsValidPID( 0x%08lx ) failed!\n", pid );
  345.     return FALSE;
  346. }
  347.  
  348.  
  349. struct ARexxPort *
  350. Process_GetRexxPort( U32 pid )
  351. {
  352.     struct ProcEnv *env = (struct ProcEnv *)pid;
  353.  
  354.     if (Process_IsValidPID( pid ))
  355.     {
  356.         return env->RexxPort;
  357.     }
  358.  
  359.     return NULL;
  360. }
  361.  
  362.